import os
import yaml
import base64
import requests
# 解码base64密码
def decode_base64(encoded_value):
    try:
        return base64.b64decode(encoded_value).decode('utf-8')
    except:
        return encoded_value
        
# 读取文件内容并替换
def replace_in_file(file_path):
    # 打开文件并读取内容
    with open(file_path, 'r') as file:
        content = file.read()
    
    # 替换所有的 \\" 为 "
    content = content.replace(r'\\"', '"')
    
    # 打开文件并写入修改后的内容
    with open(file_path, 'w') as file:
        file.write(content)

# 加载替换规则
def load_rules(config_file):
    rules = {}
    with open(config_file, 'r', encoding='utf-8') as file:
        for line in file:
            if '|' in line and not line.strip().startswith('#'):  # 忽略注释和空行
                left, right = line.strip().split('|', 1)
                rules[left] = right
    return rules

# 批量替换函数
def apply_replace_rules(content, replace_rules):
    for old, new in replace_rules.items():
        content = content.replace(old, new)
    return content

def update_yaml_params(data, input_dict):
    if isinstance(data, list):
        # 如果当前是列表，递归处理每个项
        for item in data:
            update_yaml_params(item, input_dict)
    elif isinstance(data, dict):
        # 如果当前是字典，检查是否包含 'env' 字段
        for key, value in data.items():
            if key == "env" and isinstance(value, list):
                # 如果 'env' 是一个列表，处理每个环境变量
                for env_item in value:
                    # 如果 'name' 与 input_dict 中的键匹配，且 'value' 字段存在
                    if 'name' in env_item and env_item['name'] in input_dict:
                        # 确保 'value' 字段存在再进行更新
                        if 'value' in env_item:
                            env_item['value'] = input_dict[env_item['name']]  # 更新值
            else:
                # 递归处理其他字典项
                update_yaml_params(value, input_dict)
    return data

# 批量修改密码
def update_passwords(yaml_content, password_rules, path=".stringData"):
    keys = path.strip('.').split('.')
    string_data = yaml_content
    for key in keys:
        if isinstance(string_data, dict) and key in string_data:
            string_data = string_data[key]
        else:
            return yaml_content  # 找不到路径，直接返回
    if isinstance(string_data, dict):
        for k, v in string_data.items():
            # 尝试解密每一个值
            string_data[k] = decode_base64(v)
        for key, new_value in password_rules.items():
            if key in string_data:
                string_data[key] = new_value
    return yaml_content

# 处理单个文件
def process_file(source_path, target_path, replace_rules, param_rules, password_rules):
    with open(source_path, 'r', encoding='utf-8') as file:
        content = file.read()
    # 在处理 YAML 内容之前先将所有的 " 替换为 \\
    content = content.replace('"', '\\"')
    # 按 "---" 分段
    sections = content.split('---')
    processed_sections = []
    
    for section in sections:
        section = section.strip()
        if section:
            try:
                # 尝试解析为 YAML
                yaml_content = yaml.safe_load(section)
                
                # 应用替换规则
                section = apply_replace_rules(str(yaml_content), replace_rules)
                yaml_content = yaml.safe_load(section)

                # 处理 Secret 资源
                if isinstance(yaml_content, dict) and yaml_content.get('kind') == 'Secret':
                    if 'data' in yaml_content:
                        yaml_content['stringData'] = yaml_content['data']
                        del yaml_content['data']

                # 修改参数值
                yaml_content = update_yaml_params(yaml_content, param_rules)
                
                # 修改密码
                yaml_content = update_passwords(yaml_content, password_rules)

                # 添加到处理后的段落列表
                processed_sections.append(yaml.dump(yaml_content, default_flow_style=False))
            except yaml.YAMLError as e:
                print(f"Error parsing YAML in section: {e}")
                continue
    
    # 拼接处理后的内容
    processed_content = '\n---\n'.join(processed_sections)
    
    # 确保目标目录存在
    os.makedirs(os.path.dirname(target_path), exist_ok=True)
    
    # 写回目标文件
    with open(target_path, 'w', encoding='utf-8') as file:
        file.write(processed_content)
        print(f"Processed file written to: {target_path}")
        
    #二次处理target_path
    replace_in_file(target_path)

# 主函数
def process_directory(source_dir, target_dir, replace_config, param_config, pass_config):
    # 加载配置
    replace_rules = load_rules(replace_config)
    param_rules = load_rules(param_config)
    password_rules = load_rules(pass_config)
    
    # 遍历源目录中的文件
    for filename in os.listdir(source_dir):
        source_path = os.path.join(source_dir, filename)
        target_path = os.path.join(target_dir, filename)
        
        if os.path.isfile(source_path):
#            print(f"Processing file: {source_path}")
            process_file(source_path, target_path, replace_rules, param_rules, password_rules)

if __name__ == "__main__":
    # 交互式输入项目名称
    project_name = input("请输入项目名称: ").strip()
    
    while not project_name:
        project_name = input("项目名称不能为空，请重新输入: ").strip()

    # 设置基础URL和目录
    base_url = "http://172.16.102.22:23657/private_deploy/format_yaml"
    source_dir = '.'
    target_dir = './target'
    config_dir = './config'
    
    # 创建必要的目录
    os.makedirs(target_dir, exist_ok=True)
    os.makedirs(config_dir, exist_ok=True)
    
    # 配置文件URL
    replace_config = f'{base_url}/{project_name}/replace.txt'
    param_config = f'{base_url}/{project_name}/ch_param.txt'
    pass_config = f'{base_url}/{project_name}/ch_pass.txt'

    # 下载配置文件
    config_files = {
        'replace.txt': replace_config,
        'ch_param.txt': param_config,
        'ch_pass.txt': pass_config
    }

    try:
        for filename, url in config_files.items():
            response = requests.get(url)
            if response.status_code == 200:
                config_path = os.path.join(config_dir, filename)
                with open(config_path, 'w', encoding='utf-8') as f:
                    f.write(response.text)
            else:
                print(f"Error: Failed to download {filename}")
                exit(1)
        
        # 更新配置文件路径为本地路径
        replace_config = os.path.join(config_dir, 'replace.txt')
        param_config = os.path.join(config_dir, 'ch_param.txt')
        pass_config = os.path.join(config_dir, 'ch_pass.txt')

        if os.path.exists(replace_config) and os.path.exists(param_config) and os.path.exists(pass_config) and os.path.isdir(source_dir):
            process_directory(source_dir, target_dir, replace_config, param_config, pass_config)
        else:
            print("Error: Config files or source directory not found.")
    except requests.exceptions.RequestException as e:
        print(f"Error downloading config files: {e}")